Skip to content

fix(ec2): DescribeVolumes MaxResults guard + change_state TOCTOU + empty-filter-value (bug-hunt)#2297

Merged
vieiralucas merged 1 commit into
mainfrom
bh-ec2-pag-toctou
Jul 16, 2026
Merged

fix(ec2): DescribeVolumes MaxResults guard + change_state TOCTOU + empty-filter-value (bug-hunt)#2297
vieiralucas merged 1 commit into
mainfrom
bh-ec2-pag-toctou

Conversation

@vieiralucas

@vieiralucas vieiralucas commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

Three EC2 bugs from the 2026-07-16 bug-hunt (all silent wrong-behavior):

  • 1.1 (HIGH) DescribeVolumes infinite loop — it was the only one of EC2's five paginators missing the validate_max_results guard. MaxResults=0 produced an empty <volumeSet/> plus <nextToken>0</nextToken> pointing back at offset 0 → a paginating client loops forever. Now returns InvalidParameterValue like the four siblings (and like AWS).
  • 4.1 (MED) change_state TOCTOU resurrection — Start/Stop/Terminate validated the transition + stop/termination protection under a read() guard, dropped it, then applied the new state under write() with no re-check. A concurrent TerminateInstances landing in the window let a StartInstances overwrite code 48 with pending, resurrecting a terminated instance past the boot task's terminal guard. Extracted check_transition and re-run it against freshly re-read state inside the write lock; the whole call is now atomic.
  • 1.11 (LOW) empty filter value truncationFilter.N.Value.M= (a legitimate empty/absent-tag-value filter) truncated the value list. Added indexed_list_keep_empty for filter values; id-lists (InstanceId.N etc.) keep the original empty-terminates semantics so there's no blast radius.

Test plan

  • check_transition_enforces_terminal_and_protection (unit) + start_after_terminate_does_not_resurrect (tokio integration) — resurrection is rejected, state untouched.
  • describe_volumes_rejects_max_results_zero / _above_max, describe_volumes_paginates.
  • indexed_list_empty_value_terminates_for_id_lists, indexed_list_keep_empty_*, parse_filters_keeps_empty_filter_value.
  • cargo test -p fakecloud-ec2 --lib → 132 passed; clippy --all-targets -D warnings clean; fmt applied.

Behavior-only fix — no API-surface, SDK, docs, or count changes.


Summary by cubic

Fixes three EC2 behavior bugs: prevents infinite pagination in DescribeVolumes, makes instance state changes atomic to close a TOCTOU gap, and preserves empty filter values during parsing. Behavior-only and aligns errors with AWS.

  • Bug Fixes
    • DescribeVolumes: enforce MaxResults range (5–1000); 0 or >1000 now returns InvalidParameterValue instead of looping with a self-referential NextToken.
    • Start/Stop/Terminate: re-check transition and protections inside the write lock; prevents resurrection after a concurrent terminate; batch calls remain atomic (all-or-nothing).
    • Filters: keep empty filter values (Filter.N.Value.M=) using indexed_list_keep_empty; ID lists still treat empty members as terminators.

Written for commit 6865aec. Summary will update on new commits.

Review in cubic

…der write + empty-filter-value (bug-hunt)

- DescribeVolumes: add validate_max_results(5,1000) guard its 4 sibling
  paginators already have; MaxResults=0 now returns InvalidParameterValue
  instead of an empty page with a self-referential nextToken=0 (infinite loop).
- change_state (Start/Stop/Terminate): extract check_transition and re-run the
  transition + stop/termination-protection checks against freshly-re-read state
  INSIDE the write lock, so a concurrent Terminate landing between the read
  check and the write can no longer resurrect a terminated instance (finding
  4.1). Whole call stays atomic under the held guard.
- parse_filters: add indexed_list_keep_empty so a present-but-empty filter
  value (Filter.N.Value.M=) is a legitimate empty-string member instead of
  truncating; id-lists keep original empty-terminates semantics (no blast
  radius on InstanceId.N etc.).
@vieiralucas vieiralucas requested a review from Copilot July 16, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@vieiralucas vieiralucas requested a review from Copilot July 16, 2026 13:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@vieiralucas vieiralucas merged commit 834a041 into main Jul 16, 2026
156 checks passed
@vieiralucas vieiralucas deleted the bh-ec2-pag-toctou branch July 16, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants